home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / ddx / cfb / cfbfillarc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-15  |  6.4 KB  |  274 lines

  1. /************************************************************
  2. Copyright 1989 by The Massachusetts Institute of Technology
  3.  
  4. Permission to use, copy, modify, and distribute this
  5. software and its documentation for any purpose and without
  6. fee is hereby granted, provided that the above copyright
  7. notice appear in all copies and that both that copyright
  8. notice and this permission notice appear in supporting
  9. documentation, and that the name of MIT not be used in
  10. advertising or publicity pertaining to distribution of the
  11. software without specific prior written permission.
  12. M.I.T. makes no representation about the suitability of
  13. this software for any purpose. It is provided "as is"
  14. without any express or implied warranty.
  15.  
  16. ********************************************************/
  17.  
  18. /* $XConsortium: cfbfillarc.c,v 5.8 89/11/24 18:10:58 rws Exp $ */
  19.  
  20. #include "X.h"
  21. #include "Xprotostr.h"
  22. #include "miscstruct.h"
  23. #include "gcstruct.h"
  24. #include "pixmapstr.h"
  25. #include "scrnintstr.h"
  26. #include "cfb.h"
  27. #include "cfbmskbits.h"
  28. #include "mifillarc.h"
  29.  
  30. extern void miPolyFillArc();
  31.  
  32. /* gcc 1.35 is stupid */
  33. #if defined(__GNUC__) && defined(mc68020)
  34. #define STUPID volatile
  35. #else
  36. #define STUPID
  37. #endif
  38.  
  39. static void
  40. cfbFillEllipseSolidCopy(pDraw, pGC, arc)
  41.     DrawablePtr pDraw;
  42.     GCPtr pGC;
  43.     xArc *arc;
  44. {
  45.     int iscircle;
  46.     STUPID int x, y, e, ex;
  47.     STUPID int yk, xk, ym, xm, dx, dy, xorg, yorg;
  48.     miFillArcRec info;
  49.     int *addrlt, *addrlb;
  50.     register int *addrl;
  51.     register int n;
  52.     int nlwidth;
  53.     register int fill, xpos;
  54.     register int slw;
  55.     int startmask, endmask, nlmiddle;
  56.  
  57.     if (pDraw->type == DRAWABLE_WINDOW)
  58.     {
  59.     addrlt = (int *)
  60.            (((PixmapPtr)(pDraw->pScreen->devPrivate))->devPrivate.ptr);
  61.     nlwidth = (int)
  62.            (((PixmapPtr)(pDraw->pScreen->devPrivate))->devKind) >> 2;
  63.     }
  64.     else
  65.     {
  66.     addrlt = (int *)(((PixmapPtr)pDraw)->devPrivate.ptr);
  67.     nlwidth = (int)(((PixmapPtr)pDraw)->devKind) >> 2;
  68.     }
  69.     fill = PFILL(pGC->fgPixel);
  70.     miFillArcSetup(arc, &info);
  71.     MIFILLARCSETUP();
  72.     xorg += pDraw->x;
  73.     yorg += pDraw->y;
  74.     addrlb = addrlt;
  75.     addrlt += nlwidth * (yorg - y);
  76.     addrlb += nlwidth * (yorg + y + dy);
  77.     iscircle = (arc->width == arc->height);
  78.     while (y)
  79.     {
  80.     addrlt += nlwidth;
  81.     addrlb -= nlwidth;
  82.     if (iscircle)
  83.     {
  84.         MIFILLCIRCSTEP(slw);
  85.     }
  86.     else
  87.     {
  88.         MIFILLELLSTEP(slw);
  89.         if (!slw)
  90.         continue;
  91.     }
  92.     xpos = xorg - x;
  93.     addrl = addrlt + (xpos >> PWSH);
  94.     if (((xpos & PIM) + slw) <= PPW)
  95.     {
  96.         maskpartialbits(xpos, slw, startmask);
  97.         *addrl = (*addrl & ~startmask) | (fill & startmask);
  98.         if (miFillArcLower(slw))
  99.         {
  100.         addrl = addrlb + (xpos >> PWSH);
  101.         *addrl = (*addrl & ~startmask) | (fill & startmask);
  102.         }
  103.         continue;
  104.     }
  105.     maskbits(xpos, slw, startmask, endmask, nlmiddle);
  106.     if (startmask)
  107.     {
  108.         *addrl = (*addrl & ~startmask) | (fill & startmask);
  109.         addrl++;
  110.     }
  111.     for (n = nlmiddle; n--; )
  112.         *addrl++ = fill;
  113.     if (endmask)
  114.         *addrl = (*addrl & ~endmask) | (fill & endmask);
  115.     if (!miFillArcLower(slw))
  116.         continue;
  117.     addrl = addrlb + (xpos >> PWSH);
  118.     if (startmask)
  119.     {
  120.         *addrl = (*addrl & ~startmask) | (fill & startmask);
  121.         addrl++;
  122.     }
  123.     for (n = nlmiddle; n--; )
  124.         *addrl++ = fill;
  125.     if (endmask)
  126.         *addrl = (*addrl & ~endmask) | (fill & endmask);
  127.     }
  128. }
  129.  
  130. #define FILLSPAN(xl,xr,addr) \
  131.     if (xr >= xl) \
  132.     { \
  133.     n = xr - xl + 1; \
  134.     addrl = addr + (xl >> PWSH); \
  135.     if (((xl & PIM) + n) <= PPW) \
  136.     { \
  137.         maskpartialbits(xl, n, startmask); \
  138.         *addrl = (*addrl & ~startmask) | (fill & startmask); \
  139.     } \
  140.     else \
  141.     { \
  142.         maskbits(xl, n, startmask, endmask, n); \
  143.         if (startmask) \
  144.         { \
  145.         *addrl = (*addrl & ~startmask) | (fill & startmask); \
  146.         addrl++; \
  147.         } \
  148.         while (n--) \
  149.         *addrl++ = fill; \
  150.         if (endmask) \
  151.         *addrl = (*addrl & ~endmask) | (fill & endmask); \
  152.     } \
  153.     }
  154.  
  155. #define FILLSLICESPANS(flip,addr) \
  156.     if (!flip) \
  157.     { \
  158.     FILLSPAN(xl, xr, addr); \
  159.     } \
  160.     else \
  161.     { \
  162.     xc = xorg - x; \
  163.     FILLSPAN(xc, xr, addr); \
  164.     xc += slw - 1; \
  165.     FILLSPAN(xl, xc, addr); \
  166.     }
  167.  
  168. static void
  169. cfbFillArcSliceSolidCopy(pDraw, pGC, arc)
  170.     DrawablePtr pDraw;
  171.     GCPtr pGC;
  172.     xArc *arc;
  173. {
  174.     int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
  175.     register int x, y, e, ex;
  176.     miFillArcRec info;
  177.     miArcSliceRec slice;
  178.     int xl, xr, xc;
  179.     int iscircle;
  180.     int *addrlt, *addrlb;
  181.     register int *addrl;
  182.     register int n;
  183.     int nlwidth;
  184.     register int fill;
  185.     int startmask, endmask;
  186.  
  187.     if (pDraw->type == DRAWABLE_WINDOW)
  188.     {
  189.     addrlt = (int *)
  190.            (((PixmapPtr)(pDraw->pScreen->devPrivate))->devPrivate.ptr);
  191.     nlwidth = (int)
  192.            (((PixmapPtr)(pDraw->pScreen->devPrivate))->devKind) >> 2;
  193.     }
  194.     else
  195.     {
  196.     addrlt = (int *)(((PixmapPtr)pDraw)->devPrivate.ptr);
  197.     nlwidth = (int)(((PixmapPtr)pDraw)->devKind) >> 2;
  198.     }
  199.     fill = PFILL(pGC->fgPixel);
  200.     miFillArcSetup(arc, &info);
  201.     miFillArcSliceSetup(arc, &slice, pGC);
  202.     MIFILLARCSETUP();
  203.     iscircle = (arc->width == arc->height);
  204.     xorg += pDraw->x;
  205.     yorg += pDraw->y;
  206.     addrlb = addrlt;
  207.     addrlt += nlwidth * (yorg - y);
  208.     addrlb += nlwidth * (yorg + y + dy);
  209.     slice.edge1.x += pDraw->x;
  210.     slice.edge2.x += pDraw->x;
  211.     while (y > 0)
  212.     {
  213.     addrlt += nlwidth;
  214.     addrlb -= nlwidth;
  215.     if (iscircle)
  216.     {
  217.         MIFILLCIRCSTEP(slw);
  218.     }
  219.     else
  220.     {
  221.         MIFILLELLSTEP(slw);
  222.     }
  223.     MIARCSLICESTEP(slice.edge1);
  224.     MIARCSLICESTEP(slice.edge2);
  225.     if (miFillSliceUpper(slice))
  226.     {
  227.         MIARCSLICEUPPER(xl, xr, slice, slw);
  228.         FILLSLICESPANS(slice.flip_top, addrlt);
  229.     }
  230.     if (miFillSliceLower(slice))
  231.     {
  232.         MIARCSLICELOWER(xl, xr, slice, slw);
  233.         FILLSLICESPANS(slice.flip_bot, addrlb);
  234.     }
  235.     }
  236. }
  237.  
  238. void
  239. cfbPolyFillArcSolidCopy(pDraw, pGC, narcs, parcs)
  240.     DrawablePtr    pDraw;
  241.     GCPtr    pGC;
  242.     int        narcs;
  243.     xArc    *parcs;
  244. {
  245.     register xArc *arc;
  246.     register int i;
  247.     BoxRec box;
  248.     RegionPtr cclip;
  249.  
  250.     cclip = ((cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip;
  251.     for (arc = parcs, i = narcs; --i >= 0; arc++)
  252.     {
  253.     if (miFillArcEmpty(arc))
  254.         continue;
  255.     if (miCanFillArc(arc))
  256.     {
  257.         box.x1 = arc->x + pDraw->x;
  258.         box.y1 = arc->y + pDraw->y;
  259.         box.x2 = box.x1 + (int)arc->width + 1;
  260.         box.y2 = box.y1 + (int)arc->height + 1;
  261.         if ((*pDraw->pScreen->RectIn)(cclip, &box) == rgnIN)
  262.         {
  263.         if ((arc->angle2 >= FULLCIRCLE) ||
  264.             (arc->angle2 <= -FULLCIRCLE))
  265.             cfbFillEllipseSolidCopy(pDraw, pGC, arc);
  266.         else
  267.             cfbFillArcSliceSolidCopy(pDraw, pGC, arc);
  268.         continue;
  269.         }
  270.     }
  271.     miPolyFillArc(pDraw, pGC, 1, arc);
  272.     }
  273. }
  274.